using System.Linq;
using Daemon.Common;
using Daemon.Common.Helpers;
using Daemon.Infrustructure.EF;
using Daemon.Repository.EF.Enums;
using Daemon.Repository.Contract;
using Daemon.Model;
using System;
using System.Linq.Expressions;
using System.Collections.Generic;
namespace Daemon.Repository.EF
{
    public class StudentScoreRepository : Repository<StudentScore>, IStudentScoreRepository
    {
        protected override Expression<Func<StudentScore, int>> PrimaryKeyExpression => r => r.Id;

        public StudentScoreRepository(ApiDBContent context) : base(context)
        {
        }

        protected override IQueryable<StudentScore> FilterByAuthInfo(IQueryable<StudentScore> queryable, ApiDBContent context)
        {
            if (AuthInfo.IsAdmin)
            {
                return queryable;
            }

            queryable = queryable.Where(r => r.AddUserId == AuthInfo.UserId);
            return queryable;
        }

        protected override IEnumerable<StudentScore> IncludeRelationships(IEnumerable<StudentScore> entities, ApiDBContent db)
        {
            SetStageInfo(entities, db);
            SetStudentInfo(entities, db);
            SetClassGradeInfo(entities, db);
            return entities;
        }

        private void SetClassGradeInfo(IEnumerable<StudentScore> entities, ApiDBContent db)
        {
            if (!RouteParameterHelper.CheckRouteParameter(RelationshipNames, StudentScoreRelationship.ClassGradeInfo))
            {
                return;
            }

            var classIds = entities.Select(r => r.ClassId).ToList();
            var gradeIds = entities.Select(r => r.GradeId).ToList();
            var classDic = db.StudentClasses.Where(r => classIds.Contains(r.Id)).ToDictionary(r => r.Id, r => r.Name);
            var gradeDic = db.StudentGrade.Where(r => gradeIds.Contains(r.Id)).ToDictionary(r => r.Id, r => r.Name);
            foreach (var entity in entities)
            {
                if (classDic.TryGetValue(entity.ClassId, out string className))
                {
                    entity.ClassName = className;
                }

                if (gradeDic.TryGetValue(entity.GradeId, out string gradeName))
                {
                    entity.GradeName = gradeName;
                }
            }
        }

        private void SetStageInfo(IEnumerable<StudentScore> entities, ApiDBContent db)
        {
            if (!RouteParameterHelper.CheckRouteParameter(RelationshipNames, StudentScoreRelationship.StageInfo))
            {
                return;
            }

            var stageIds = entities.Select(r => r.StageId).ToList();
            var stageDic = db.StudentStages.Where(r => stageIds.Contains(r.Id)).ToDictionary(r => r.Id, r => r);
            foreach (var entity in entities)
            {
                if (stageDic.TryGetValue(entity.StageId, out StudentStage stage))
                {
                    entity.StageName = stage.Name;
                }
            }
        }

        private void SetStudentInfo(IEnumerable<StudentScore> entities, ApiDBContent db)
        {
            if (!RouteParameterHelper.CheckRouteParameter(RelationshipNames, StudentScoreRelationship.StudentInfo))
            {
                return;
            }

            var studentIds = entities.Select(r => r.StudentId).ToList();
            var studentDic = db.Student.Where(r => studentIds.Contains(r.Id)).ToDictionary(r => r.Id, r => r);
            var studentSchoolIds = studentDic.Values.Select(r => r.SchoolId).ToList();
            var schoolDic = db.StudentSchools.Where(r => studentSchoolIds.Contains(r.Id)).ToDictionary(r => r.Id, r => r.Name);
            foreach (var entity in entities)
            {
                if (studentDic.TryGetValue(entity.StudentId, out Student student))
                {
                    entity.StudentName = student.Name;
                    if (student.SchoolId.HasValue && schoolDic.TryGetValue(student.SchoolId.Value, out string schoolName))
                    {
                        entity.SchoolName = schoolName;
                    }
                }
            }
        }
    }
}